/*
 * MIT License
 *
 * Copyright (c) 2019 Mr.css
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

package cn.seaboot.commons.lang;

import java.io.File;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.Collator;
import java.time.ZoneId;
import java.util.Locale;
import java.util.TimeZone;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 全局参数配置
 * <p>
 * 常用的参数、编码、时区、国际化等的配置。
 * <p>
 * 这个类的命名，参考率了安卓中的 R，记录了全局的关键参数。
 *
 * @author Mr.css 2018-07-13 11:06:18
 * @see StandardCharsets
 */
public class P {
    private P() {
    }

    private static final Logger logger = LoggerFactory.getLogger(P.class);

    /**
     * UTF-8
     */
    public static final String UTF_8 = "UTF-8";

    /**
     * GBK
     */
    public static final String GBK = "GBK";

    /**
     * ISO-8859-1
     */
    public static final String ISO_8859_1 = "ISO-8859-1";

    /**
     * 紧凑日期时间格式: yyyyMMddHHmmss
     */
    public static final String DATE_FORMAT_COMPACT_DATETIME = "yyyyMMddHHmmss";
    /**
     * 紧凑日期格式: yyyyMMdd
     */
    public static final String DATE_FORMAT_COMPACT_DATE = "yyyyMMdd";

    /**
     * 紧凑时间格式: yyyyMMddHHmmss
     */
    public static final String DATE_FORMAT_COMPACT_TIME = "HHmmss";

    /**
     * 格式化(24小时制)<br> yyyy-MM-dd HH:mm:ss
     */
    public static final String DATE_FORMAT_DATETIME = "yyyy-MM-dd HH:mm:ss";

    /**
     * 格式化(12小时制)<br> yyyy-MM-dd hh:mm:ss
     */
    public static final String DATE_FORMAT_DATETIME_12 = "yyyy-MM-dd hh:mm:ss";

    /**
     * 格式化日期: yyyy-MM-dd
     */
    public static final String DATE_FORMAT_DATE = "yyyy-MM-dd";

    /**
     * 格式化(24小时制)时间: HH:mm:ss
     */
    public static final String DATE_FORMAT_TIME = "HH:mm:ss";

    /**
     * 格式化(12小时制)时间: hh:mm:ss
     */
    public static final String DATE_FORMAT_TIME_12 = "hh:mm:ss";

    /**
     * 格式化日期: yyyy-MM
     */
    public static final String DATE_FORMAT_MONTH = "yyyy-MM";

    /**
     * 格式化日期: yyyy-MM-dd HH
     */
    public static final String DATE_FORMAT_HOUR = "yyyy-MM-dd HH";

    /**
     * 格式化日期: yyyy-MM-dd HH:mm
     */
    public static final String DATE_FORMAT_MINUTE = "yyyy-MM-dd HH:mm";

    /**
     * 二进制16
     **/
    public static final int HASH_HEX = 0xf;

    /**
     * 非数字
     */
    @SuppressWarnings(Warning.ALL)
    public static final double NaN = 0.0D / 0.0;
    /**
     * 无穷大
     */
    @SuppressWarnings(Warning.ALL)
    public static final double Infinity = 1.0D / 0.0;
    /**
     * KB 数值
     */
    public static final long KB = 1024;
    /**
     * MB 数值
     */
    public static final long MB = 1024 * 1024;
    /**
     * GB 数值
     */
    public static final long GB = 1024 * 1024 * 1024;

    /**
     * KB 数值
     */
    public static final long MS_DAY = 1000 * 60 * 60 * 24;
    /**
     * MB 数值
     */
    public static final long MS_HOUR = 1000 * 60 * 60;
    /**
     * GB 数值
     */
    public static final long MS_MINUTE = 1000 * 60;
    /**
     * GB 数值
     */
    public static final long MS_SECOND = 1000;

    /**
     * UNIX换行符
     */
    public static final String LINE_SEPARATOR_UNIX = "\n";

    /**
     * Windows换行符
     */
    public static final String LINE_SEPARATOR_WINDOWS = "\r\n";

    /**
     * The Unix separator character.
     */
    public static final char UNIX_SEPARATOR = '/';

    /**
     * The Windows separator character.
     */
    public static final char WINDOWS_SEPARATOR = '\\';

    //------------------------------ 全局配置 start ------------------------------

    /**
     * 默认的纯文本编码
     */
    private static Charset charset = Charset.defaultCharset();
    /**
     * 国际化配置
     */
    private static Locale locale = Locale.CHINA;
    /**
     * 排序器，主要用于汉字排序
     */
    private static Collator collator = Collator.getInstance(locale());
    /**
     * 时区配置
     */
    private static TimeZone timeZone = TimeZone.getTimeZone("GMT+:08:00");
    /**
     * java-8 日期时区配置
     */
    private static ZoneId zoneId = ZoneId.systemDefault();

    /**
     * 默认换行符
     */
    private static String lineSeparator = LINE_SEPARATOR_WINDOWS;

    /**
     * 文件名编码
     * <p>
     * 受影响功能：开发文件下载功能时，采用的文件编码
     */
    private static String filenameEncode = UTF_8;

    /**
     * Determines if Windows file system is in use.
     *
     * @return true if the system is Windows
     */
    public static boolean isSystemWindows() {
        return File.separatorChar == WINDOWS_SEPARATOR;
    }

    public static Locale locale() {
        return locale;
    }

    public static Collator collator() {
        return collator;
    }

    public static TimeZone timeZone() {
        return timeZone;
    }

    public static String lineSeparator() {
        return lineSeparator;
    }

    public static ZoneId zoneId() {
        return zoneId;
    }

    public static void setLocale(Locale locale) {
        P.locale = locale;
        P.collator = Collator.getInstance(locale);
        logger.info("Setting Locale: {}", locale);
    }

    public static void setTimeZone(TimeZone timeZone) {
        P.timeZone = timeZone;
        logger.info("Setting TimeZone: {}", timeZone);
    }

    public static void setLineSeparator(String lineSeparator) {
        P.lineSeparator = lineSeparator;
        logger.info("Setting LineSeparator: {}", lineSeparator);
    }

    public static void setZoneId(ZoneId zoneId) {
        P.zoneId = zoneId;
    }

    /**
     * 推荐直接调用 Charset.defaultCharset()
     *
     * @return 默认编码
     */
    public static Charset charset() {
        return charset;
    }

    public static void setCharset(Charset charset) {
        P.charset = charset;
        logger.info("Setting Charset: {}", charset);
    }

    public static String filenameEncode() {
        return filenameEncode;
    }

    public static void setFilenameEncode(String filenameEncode) {
        P.filenameEncode = filenameEncode;
        logger.info("Setting FilenameEncode: {}", filenameEncode);
    }
}
